#include "app.h"
#include "hem_common.h"
#include "drv_pi.h"
#include "drv_usart2.h"
#include "lib.h"
#include "flash.h"

#define HEK1016_MODULE_NUMBER 4/*16总线面板个数*/

extern io_t *gp_io;

float g_pi_frequencyLast[ePiNumer]     = { 0 }; // 频率，DI24频率
float g_pi_dutyLast[ePiNumer]          = { 0 }; // 占空比
uint32_t g_pi_disconnect_cnt[ePiNumer] = { 0 };

/**
 * @brief 频率信号消失后的数据处理，放到500us中断里面
 */
void pi_cutoff_handler(uint32_t tick)
{
  uint8_t i = 0;
  if(tick%TIME_OUT_100MS == 0)    //100ms
  {
    for(i = 0;i < ePiNumer;i++)
    {
        if(g_pi_frequency[i] != g_pi_frequencyLast[i])
        {
            g_pi_frequencyLast[i] = g_pi_frequency[i];
            g_pi_disconnect_cnt[i] = 0;
        }
        else
        {
            g_pi_disconnect_cnt[i]++;
        }
        if(g_pi_disconnect_cnt[i] > 12)  //1.2S后清零
        {
            g_pi_frequency[i] = 0;
            g_pi_duty[i] = 0;
            g_pi_frequencyLast[i] = 0;
            g_pi_dutyLast[i] = 0;
        }
    }
  }
}
/*总线面板定时发送标志*/
uint8_t uc_hek1016_can_tx_flag[HEK1016_MODULE_NUMBER] = { 0,0,0,0 };
/*16键总线面板接收ID*/
uint32_t ul_hek1016_rx_id[HEK1016_MODULE_NUMBER] = {HEK1016_RX_ID_01, HEK1016_RX_ID_02, HEK1016_RX_ID_03, HEK1016_RX_ID_04};
/*16键总线面板第一个发送ID*/
uint32_t ul_hek1016_tx_id_first[HEK1016_MODULE_NUMBER]  = {HEK1016_TX_ID_F01, HEK1016_TX_ID_F02, HEK1016_TX_ID_F03, HEK1016_TX_ID_F04};
/*16键总线面板第二个发送ID*/
uint32_t ul_hek1016_tx_id_second[HEK1016_MODULE_NUMBER] = {HEK1016_TX_ID_S01, HEK1016_TX_ID_S02, HEK1016_TX_ID_S03, HEK1016_TX_ID_S04};

uint8_t uc_hek1016_backlight[HEK1016_MODULE_NUMBER] = { 1,1,1,1 };
uint8_t uc_hek1016_key01_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key01_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key01_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key02_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key02_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key02_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key03_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key03_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key03_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key04_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key04_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key04_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key05_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key05_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key05_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key06_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key06_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key06_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key07_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key07_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key07_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key08_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key08_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key08_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key09_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key09_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key09_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key10_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key10_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key10_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key11_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key11_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key11_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key12_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key12_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key12_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key13_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key13_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key13_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key14_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key14_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key14_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key15_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key15_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key15_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
uint8_t uc_hek1016_key16_led_red[HEK1016_MODULE_NUMBER]   = { 0 };
uint8_t uc_hek1016_key16_led_green[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key16_led_blue[HEK1016_MODULE_NUMBER]  = { 0 };
void hek1016_can0_tx(uint8_t mod)
{
  uint8_t buf[8] = { 0 };

  if(uc_hek1016_can_tx_flag[0] == 0) return;
  uc_hek1016_can_tx_flag[0] = 0;

  buf[0] = (uc_hek1016_key01_led_red[mod]  <<0) | (uc_hek1016_key02_led_red[mod]  <<1) | (uc_hek1016_key03_led_red[mod]  <<2) | (uc_hek1016_key04_led_red[mod]  <<3) |
           (uc_hek1016_key05_led_red[mod]  <<4) | (uc_hek1016_key06_led_red[mod]  <<5) | (uc_hek1016_key07_led_red[mod]  <<6) | (uc_hek1016_key08_led_red[mod]  <<7);
  buf[1] = (uc_hek1016_key01_led_green[mod]<<0) | (uc_hek1016_key02_led_green[mod]<<1) | (uc_hek1016_key03_led_green[mod]<<2) | (uc_hek1016_key04_led_green[mod]<<3) |
           (uc_hek1016_key05_led_green[mod]<<4) | (uc_hek1016_key06_led_green[mod]<<5) | (uc_hek1016_key07_led_green[mod]<<6) | (uc_hek1016_key08_led_green[mod]<<7);
  buf[2] = (uc_hek1016_key01_led_blue[mod] <<0) | (uc_hek1016_key02_led_blue[mod] <<1) | (uc_hek1016_key03_led_blue[mod] <<2) | (uc_hek1016_key04_led_blue[mod] <<3) |
           (uc_hek1016_key05_led_blue[mod] <<4) | (uc_hek1016_key06_led_blue[mod] <<5) | (uc_hek1016_key07_led_blue[mod] <<6) | (uc_hek1016_key08_led_blue[mod] <<7);
  buf[7] = uc_hek1016_backlight[mod];
  Can0_Data_Store_Fifo(ul_hek1016_tx_id_first[mod],buf,8);

  buf[0] = (uc_hek1016_key09_led_red[mod]  <<0) | (uc_hek1016_key10_led_red[mod]  <<1) | (uc_hek1016_key11_led_red[mod]  <<2) | (uc_hek1016_key12_led_red[mod]  <<3) |
           (uc_hek1016_key13_led_red[mod]  <<4) | (uc_hek1016_key14_led_red[mod]  <<5) | (uc_hek1016_key15_led_red[mod]  <<6) | (uc_hek1016_key16_led_red[mod]  <<7);
  buf[1] = (uc_hek1016_key09_led_green[mod]<<0) | (uc_hek1016_key10_led_green[mod]<<1) | (uc_hek1016_key11_led_green[mod]<<2) | (uc_hek1016_key12_led_green[mod]<<3) |
           (uc_hek1016_key13_led_green[mod]<<4) | (uc_hek1016_key14_led_green[mod]<<5) | (uc_hek1016_key15_led_green[mod]<<6) | (uc_hek1016_key16_led_green[mod]<<7);
  buf[2] = (uc_hek1016_key09_led_blue[mod] <<0) | (uc_hek1016_key10_led_blue[mod] <<1) | (uc_hek1016_key11_led_blue[mod] <<2) | (uc_hek1016_key12_led_blue[mod] <<3) |
           (uc_hek1016_key13_led_blue[mod] <<4) | (uc_hek1016_key14_led_blue[mod] <<5) | (uc_hek1016_key15_led_blue[mod] <<6) | (uc_hek1016_key16_led_blue[mod] <<7);
  Can0_Data_Store_Fifo(ul_hek1016_tx_id_second[mod],buf,8);
}
/**
 * @brief CAN接收示例
 */
uint32_t gCan0RxCnt     = 0;//CAN总线异常判断使用参数，每接收到1帧CAN报文就加1
uint32_t gCan0RxCntLast = 0;//与gCan0RxCnt参数配合使用

uint8_t uc_hek1016_key01[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key02[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key03[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key04[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key05[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key06[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key07[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key08[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key09[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key10[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key11[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key12[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key13[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key14[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key15[HEK1016_MODULE_NUMBER] = { 0 };
uint8_t uc_hek1016_key16[HEK1016_MODULE_NUMBER] = { 0 };
/**
 * @brief 16键总线面板接收函数
 */
void hek1016_can0_rx(CAN_DATA_FORMAT_T data,uint8_t mod)
{
    if(mod >= HEK1016_MODULE_NUMBER) return;
    if(data.id != ul_hek1016_rx_id[mod]) return;
    if((data.rx_len > 8) || (data.rx_len == 0)) return;

    uc_hek1016_key01[mod] = (data.rx_data[0]>>0)&0x03;
    uc_hek1016_key02[mod] = (data.rx_data[0]>>2)&0x03;
    uc_hek1016_key03[mod] = (data.rx_data[0]>>4)&0x03;
    uc_hek1016_key04[mod] = (data.rx_data[0]>>6)&0x03;
    uc_hek1016_key05[mod] = (data.rx_data[1]>>0)&0x03;
    uc_hek1016_key06[mod] = (data.rx_data[1]>>2)&0x03;
    uc_hek1016_key07[mod] = (data.rx_data[1]>>4)&0x03;
    uc_hek1016_key08[mod] = (data.rx_data[1]>>6)&0x03;
    uc_hek1016_key09[mod] = (data.rx_data[2]>>0)&0x03;
    uc_hek1016_key10[mod] = (data.rx_data[2]>>2)&0x03;
    uc_hek1016_key11[mod] = (data.rx_data[2]>>4)&0x03;
    uc_hek1016_key12[mod] = (data.rx_data[2]>>6)&0x03;
    uc_hek1016_key13[mod] = (data.rx_data[3]>>0)&0x03;
    uc_hek1016_key14[mod] = (data.rx_data[3]>>2)&0x03;
    uc_hek1016_key15[mod] = (data.rx_data[3]>>4)&0x03;
    uc_hek1016_key16[mod] = (data.rx_data[3]>>6)&0x03;
}
/**
 * @brief CAN0接收函数，该函数不要放入循环
 * [param in] data 结构体数据
 */
void app_can0_rx(CAN_DATA_FORMAT_T data)
{
    hek1016_can0_rx(data,0);
    gCan0RxCnt++;
}
/**
 * @brief CAN1接收函数，该函数不要放入循环
 * [param in] data 结构体数据
 */
void app_can1_rx(CAN_DATA_FORMAT_T data)
{

}

#define RS485_RX_BUFF_NUMBER 128

/**
 * @brief 示例，485接收函数,不要放到循环中
 */
uint8_t g_rs485_rxBuf[RS485_RX_BUFF_NUMBER] = { 0 };
uint16_t g_rs485_rxCnt = 0;
uint32_t g_rs485_RxTotallCnt = 0;
void app_rs485_rx(uint8_t data)
{
    g_rs485_rxBuf[g_rs485_rxCnt] = data; // 将USART3接收到的数据保存到uData
    g_rs485_rxCnt++;
    g_rs485_RxTotallCnt++;
    g_rs485_rxCnt = g_rs485_rxCnt % RS485_RX_BUFF_NUMBER;
}

/**
 * @brief 示例，485发送函数
*/
uint8_t g485_TxTimeoutSn = 0;//100ms定时发送，该参数放到定时器中
uint8_t g485_data[10] = {1,2,3,4,5,6,78,90};
void rs485_send_test(void)
{
    if (g485_TxTimeoutSn == 0)
        return;
    g485_TxTimeoutSn = 0;
    rs485_send_byte(g485_data,sizeof(g485_data));
}

/**
 * @brief 示例，载入PWMI标定参数
 */
//800mA对应的值；
uint16_t g_800_ma[12] = {800,826,814,825,813,809,815,826,802,805,812,809};
uint16_t g_200_ma[12] = {200,218,212,220,213,202,213,218,190,193,210,211};
void load_pwmi_calibration_param(void)
{
  uint16_t read_buf[26]  = { 0 };
  uint16_t i = 0;
  int8_t success = 0;

  Flash_read_16bit_data(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(read_buf)/2,read_buf);
  if((read_buf[0]  == 0x5A5A) && (read_buf[25] == 0xA5A5))
  {
    for(i = 0;i < 12;i++)
    {
      if((read_buf[i+1] < 120) || (read_buf[i+1] > 280))
      {
        success = -1;
        break;
      }
      if((read_buf[i+13] < 600) || (read_buf[i+13] > 1000))
      {
        success = -1;
        break;
      }
    }

    if(success == 0)
    {
      Lib_memcpy_16bit(g_200_ma,&read_buf[1],sizeof(g_200_ma)/2);
      Lib_memcpy_16bit(g_800_ma,&read_buf[13],sizeof(g_800_ma)/2);
    }
  }
}

/**
 * @brief 示例，存储pwmi标定参数
 */
uint8_t g_pwmi_store_param_sn = 0;       //存储开关
void store_pwmi_calibration_param(void)
{
  uint16_t write_buf[26] = { 0 };
  uint16_t read_buf[26]  = { 0 };
  int a = 0,b = 0;

  if(g_pwmi_store_param_sn == 0) return;
  g_pwmi_store_param_sn = 0;

  Flash_read_16bit_data(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(read_buf)/2,read_buf);
  if((read_buf[0]  == 0x5A5A) && (read_buf[25] == 0xA5A5))
  {
    a = Lib_memcmp_16bit(&read_buf[1],g_200_ma,sizeof(g_200_ma)/2);
    b = Lib_memcmp_16bit(&read_buf[13],g_800_ma,sizeof(g_800_ma)/2);
    if((a != 0) || (b != 0))
    {
      write_buf[0]  = 0x5A5A;
      write_buf[25] = 0xA5A5;
      Lib_memcpy_16bit(&write_buf[1], g_200_ma,sizeof(g_200_ma)/2);
      Lib_memcpy_16bit(&write_buf[13],g_800_ma,sizeof(g_800_ma)/2);

      Flash_erase_page((uint32_t)PWMI_CALIBRATION_DATA_ADDR_BASE);
      Flash_write_16bit_data_with_page_erased(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(write_buf)/2,write_buf);
    }
  }
  else
  {
    write_buf[0]  = 0x5A5A;
    write_buf[25] = 0xA5A5;
    Lib_memcpy_16bit(&write_buf[1], g_200_ma,sizeof(g_200_ma)/2);
    Lib_memcpy_16bit(&write_buf[13],g_800_ma,sizeof(g_800_ma)/2);

    Flash_erase_page((uint32_t)PWMI_CALIBRATION_DATA_ADDR_BASE);
    Flash_write_16bit_data_with_page_erased(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(write_buf),write_buf);
  }
}


/*
状态指示灯：在boot程序中运行，状态指示灯每100ms闪烁一次，快闪；
	         在APP程序中运行，每500ms闪烁一次；
		       在APP程序运行初始30S，快闪，然后每500ms闪烁一次，主要用于测试
*/
uint8_t gStatusLEDFlickerTimeoutSn = 0;
uint32_t gStatusLedTimeoutCnt = TIME_OUT_500MS;
/*
错误指示灯：CAN接收通信错误，长亮，同时CAN通信指示灯快速闪烁；
           CAN发送通信错误，不亮，同时CAN通信指示灯快速闪烁
*/


/*
通信指示灯：CAN正常收发，指示灯每250ms闪烁一次；
           CAN收发错误，指示灯每100ms闪烁一次，快闪；
*/
uint8_t gCanTxFaultSn   = 0;/**CAN发送异常标志 */
uint8_t gCanRxFaultSn   = 0;/*CAN接收异常标志 */
uint32_t gCanRxFaultCnt = 0;/*CAN未收到报文错误计数*/

uint8_t gSpeedLEDFlickerTimeoutSn = 0;
uint32_t gSpeedLedTimeoutCnt = TIME_OUT_250MS;
/**
 * @brief LED 闪烁tick,放入500us中断中
 * @param[in] tick 每500us增加参数
 */
void led_tick(uint32_t tick)
{
  if (tick % TIME_OUT_100MS == 0)
	{
		if(gCan0RxCnt != gCan0RxCntLast)
		{
			gCan0RxCntLast = gCan0RxCnt;
			gCanRxFaultCnt = 0;
		}
		else
		{
			gCanRxFaultCnt++;
		}
  }
  if(tick%gSpeedLedTimeoutCnt == 0)
	{
		if(gSpeedLEDFlickerTimeoutSn == 1)
		{
			gSpeedLEDFlickerTimeoutSn = 0;
		}		
		else
		{
			gSpeedLEDFlickerTimeoutSn = 1;
		}
	}
	if(tick%gStatusLedTimeoutCnt == 0)
	{
		if(gStatusLEDFlickerTimeoutSn == 1)
		{
			gStatusLEDFlickerTimeoutSn = 0;
		}
		else
		{
			gStatusLEDFlickerTimeoutSn = 1;
		}
	}
}
/**
 * @brief 控制器有四个指示灯，其中一个是电源指示灯不能控制；
 *        其余三个可以通过软件进行控制，该函数分别对三个LED
 *        进行功能定义，用户可参考自行定义功能和重写该函数
 */
void led_ctrl(void)
{
	//CAN 接收错误判断,1S中未收到报文
	if(gCanRxFaultCnt > 10)
	{
		gCanRxFaultSn = 1;
	}
	else
	{
		gCanRxFaultSn = 0;
	}
    //状态指示灯控制
	if(gStatusLEDFlickerTimeoutSn == 1)
	{
		led_status(LED_ON);
	}
	else
	{
		led_status(LED_OFF);
	}
	//CAN通信指示灯
	if(gSpeedLEDFlickerTimeoutSn == 1)
	{
		led_can(LED_ON);
	}
	else
	{
		led_can(LED_OFF);
	}
	
	if((gCanRxFaultSn == 1) || (gCanTxFaultSn == 1))
	{
		gSpeedLedTimeoutCnt = TIME_OUT_100MS;
	}
	else
	{
		gSpeedLedTimeoutCnt = TIME_OUT_250MS;
	}
	//错误指示灯
	if(gCanRxFaultSn == 1)
	{
		led_error(LED_ON);
	}
	else
	{
		led_error(LED_OFF);
	}
}
/**
 * @brief 示例，擦除用户数据区域
 */
uint8_t g_erase_flash_sn = 0;
void app_erase_flash(void)
{
  if(g_erase_flash_sn == 0)
  {
    return;
  }
  g_erase_flash_sn = 0;

  Flash_erase_page((uint32_t)USER_DATA_ADDR_BASE);
}
/**
 * @brief 运行应用程序，用户自编写的代码函数可以放到该函数下
 */
void app_run(void)
{
  app_erase_flash();
  led_ctrl();
  store_pwmi_calibration_param();
  hek1016_can0_tx(0);
	rs485_send_test();
}


/**
 * @brief 应用程序tick
 */
void App_tick(uint32_t tick)
{
  led_tick(tick);
  pi_cutoff_handler(tick);
  if(tick%TIME_OUT_100MS == 0)    //100ms
  {
  	uc_hek1016_can_tx_flag[0] = 1;
    g485_TxTimeoutSn = 1;
  }
}





